home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 3.2 / Ham Radio Version 3.2 (Chestnut CD-ROMs)(1993).ISO / packet / n17jsrc / nr4timer.c < prev    next >
C/C++ Source or Header  |  1991-04-29  |  4KB  |  180 lines

  1. /* net/rom level 4 (transport) protocol timer management.
  2.  * Copyright 1989 by Daniel M. Frank, W9NK.  Permission granted for
  3.  * non-commercial distribution only.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include "global.h"
  8. #include "mbuf.h"
  9. #include "timer.h"
  10. #include "ax25.h"
  11. #include "lapb.h"
  12. #include "netrom.h"
  13. #include "nr4.h"
  14. #include <ctype.h>
  15.  
  16. #undef NR4DEBUG
  17.  
  18. unsigned Nr_timertype = 0;        /* default to binary exponential */
  19.  
  20. /* The ACK timer has expired without any data becoming available.
  21.  * Go ahead and send an ACK.
  22.  */
  23.  
  24. void
  25. nr4ackit(p)
  26. void *p ;
  27. {
  28.     struct nr4cb *cb  = (struct nr4cb *)p ;
  29.     struct nr4hdr rhdr ;
  30.  
  31. #ifdef NR4DEBUG
  32.     printf("ACKIT called.\n") ;
  33. #endif
  34.     if (cb->qfull)                /* Are we choked? */
  35.         rhdr.opcode = NR4OPACK | NR4CHOKE ;
  36.     else
  37.         rhdr.opcode = NR4OPACK ;
  38.     rhdr.yourindex = cb->yournum ;
  39.     rhdr.yourid = cb->yourid ;
  40.     rhdr.u.ack.rxseq = cb->rxpected ;
  41.  
  42.     nr4sframe(cb->remote.node, &rhdr, NULLBUF) ;
  43. }
  44.  
  45. /* Called when one of the transmit timers has expired */
  46.  
  47. void
  48. nr4txtimeout(p)
  49. void *p ;
  50. {
  51.     struct nr4cb *cb = (struct nr4cb *)p ;
  52.     unsigned seq ;
  53.     struct nr4txbuf *t ;
  54.  
  55.     /* Sanity check */
  56.  
  57.     if (cb->state != NR4STCON)
  58.         return ;
  59.  
  60.     /* Scan through the send window looking for expired timers */
  61.     
  62.     for (seq = cb->ackxpected ;
  63.          nr4between(cb->ackxpected, seq, cb->nextosend) ;
  64.          seq = (seq + 1) & NR4SEQMASK) {
  65.         
  66.         t = &cb->txbufs[seq % cb->window] ;
  67.  
  68.         if (t->tretry.state == TIMER_EXPIRE) {
  69.             t->tretry.state = TIMER_STOP ;    /* So we don't do it again */
  70.  
  71.             if (t->retries == Nr4retries) {
  72.                 cb->dreason = NR4RTIMEOUT ;
  73.                 nr4state(cb, NR4STDISC) ;
  74.             }
  75.  
  76.             t->retries++ ;
  77.             
  78.             /* We keep track of the highest retry count in the window. */
  79.             /* If packet times out and its new retry count exceeds the *
  80.             /* max, we update the max and bump the backoff level.  This */
  81.             /* expedient is to avoid bumping the backoff level for every */
  82.             /* expiration, since with more than one timer we would back */
  83.             /* off way too fast (and at a rate dependent on the window */
  84.             /* size! */
  85.  
  86.             if (t->retries > cb->txmax) {
  87.                 cb->blevel++ ;
  88.                 cb->txmax = t->retries ;    /* update the max */
  89.             }
  90.             
  91.             nr4sbuf(cb,seq) ;    /* Resend buffer */
  92.         }
  93.      }
  94.     
  95. }
  96.  
  97. /* Connect/disconnect acknowledgement timeout */
  98.  
  99. void
  100. nr4cdtimeout(p)
  101. void *p ;
  102. {
  103.     struct nr4cb *cb = (struct nr4cb *)p ;
  104.     struct nr4hdr hdr ;
  105.  
  106.     switch(cb->state) {
  107.       case NR4STCPEND:
  108.           if (cb->cdtries == Nr4retries) {    /* Have we tried long enough? */
  109.             cb->dreason = NR4RTIMEOUT ;
  110.             nr4state(cb, NR4STDISC) ;        /* Give it up */
  111.         } else {
  112.             /* Set up header */
  113.             
  114.             hdr.opcode = NR4OPCONRQ ;
  115.             hdr.u.conreq.myindex = cb->mynum ;
  116.             hdr.u.conreq.myid = cb->myid ;
  117.             hdr.u.conreq.window = Nr4window ;
  118.             memcpy(hdr.u.conreq.user,cb->local.user,AXALEN) ;
  119.             memcpy(hdr.u.conreq.node,cb->local.node,AXALEN) ;
  120.  
  121.             /* Bump tries counter and backoff level, and restart timer */
  122.             /* We use a linear or binary exponential backoff. */
  123.             
  124.             cb->cdtries++ ;
  125.             cb->blevel++ ;
  126.  
  127.             if(Nr_timertype)
  128.                 /* linear */
  129.                 set_timer(&cb->tcd,dur_timer(&cb->tcd)+cb->srtt);
  130.             else
  131.                 /* exponential */
  132.                 set_timer(&cb->tcd,dur_timer(&cb->tcd)*2);
  133.  
  134.             start_timer(&cb->tcd) ;
  135.  
  136.             /* Send connect request packet */
  137.  
  138.             nr4sframe(cb->remote.node,&hdr, NULLBUF) ;
  139.         }
  140.         break ;
  141.         
  142.       case NR4STDPEND:
  143.           if (cb->cdtries == Nr4retries) {    /* Have we tried long enough? */
  144.             cb->dreason = NR4RTIMEOUT ;
  145.             nr4state(cb, NR4STDISC) ;        /* Give it up */
  146.         } else {
  147.             /* Format header */
  148.             
  149.             hdr.opcode = NR4OPDISRQ ;
  150.             hdr.yourindex = cb->yournum ;
  151.             hdr.yourid = cb->yourid ;
  152.  
  153.             /* Bump retry count and start timer */
  154.             /* We don't really need to be fancy here, since we */
  155.             /* should have a good idea of the round trip time by now. */
  156.             
  157.             cb->cdtries++ ;
  158.             start_timer(&cb->tcd) ;
  159.  
  160.             /* Send disconnect request packet */
  161.  
  162.             nr4sframe(cb->remote.node,&hdr, NULLBUF) ;
  163.         }
  164.         break ;
  165.     }
  166. }
  167.  
  168. /* The choke timer has expired.  Unchoke and kick. */
  169.  
  170. void
  171. nr4unchoke(p)
  172. void *p ;
  173. {
  174.     struct nr4cb *cb = (struct nr4cb *)p ;
  175.  
  176.     cb->choked = 0 ;
  177.     nr4output(cb) ;
  178. }
  179.  
  180.